package com.yh.csx.bsf.flow.web.controller.manager;

import com.dianping.cat.util.StringUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.yh.csx.bsf.core.base.Ref;
import com.yh.csx.bsf.core.util.JsonUtils;
import com.yh.csx.bsf.flow.provider.enums.TaskStateEnum;
import com.yh.csx.bsf.flow.core.base.FlowException;
import com.yh.csx.bsf.flow.core.base.Variable;
import com.yh.csx.bsf.flow.core.base.Xml;
import com.yh.csx.bsf.flow.core.db.DbHelper;
import com.yh.csx.bsf.flow.core.util.CommonUtil;
import com.yh.csx.bsf.flow.core.util.XmlUtil;
import com.yh.csx.bsf.flow.dao.dal.t_approve_log_dal;
import com.yh.csx.bsf.flow.dao.dal.t_flow_dal;
import com.yh.csx.bsf.flow.dao.dal.t_model_dal;
import com.yh.csx.bsf.flow.dao.dal.t_task_dal;
import com.yh.csx.bsf.flow.dao.model.auto.t_approve_log_model;
import com.yh.csx.bsf.flow.dao.model.auto.t_flow_model;
import com.yh.csx.bsf.flow.dao.model.auto.t_model_model;
import com.yh.csx.bsf.flow.dao.model.auto.t_task_model;
import com.yh.csx.bsf.flow.engine.FormPermissionProvider;
import com.yh.csx.bsf.flow.engine.PaintProvider;
import com.yh.csx.bsf.flow.engine.api.UserApi;
import com.yh.csx.bsf.flow.engine.state.StateEngine;
import com.yh.csx.bsf.flow.web.base.SpringMvcController;
import com.yh.csx.bsf.flow.web.base.User;
import com.yh.csx.bsf.flow.web.base.pager.Pager1;
import lombok.val;
import lombok.var;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author: chejiangyi
 * @version: 2019-10-23 09:42
 **/
@Controller
@RequestMapping("/manager/task")
public class TaskController extends SpringMvcController {
    @RequestMapping("/index")
    public ModelAndView index(Integer flow_id,Integer id,String flow_title, String flow_approve_node, String flow_approve_by, String create_by, Integer task_state, String create_time_from,String create_time_to, Integer pageindex, Integer pagesize)
    {
        val pageIndex2=(pageindex == null?1:pageindex); val pageSize2=(pagesize == null?10:pagesize);
        html.s2("flow_id",flow_id==null?"":flow_id).s2("id",id==null?"":id).s2("flow_title",flow_title).s2("flow_approve_node",flow_approve_node).s2("flow_approve_by",flow_approve_by)
                .s2("create_by",create_by).s2("task_state", task_state==null?0:task_state).s2("create_time_from",create_time_from).s2("create_time_to",create_time_to)
                .s2("pageindex",pageindex).s2("pagesize",pagesize);
        return pageVisit((m)-> {
                    Ref<Integer> totalSize = new Ref<>(0);
                    val list = DbHelper.get(c->{
                        return new t_task_dal().getPage(c,flow_id,id, flow_title,  flow_approve_node, null, flow_approve_by,  create_by,  task_state, create_time_from, create_time_to,pageIndex2,pageSize2,totalSize);
                    });
                    new Pager1(pageIndex2,totalSize.getData()).setPageSize(pageSize2).out();
                    request.setAttribute("model",list);
                }
        );
    }
    @RequestMapping("/del")
    public ModelAndView del(Integer id) {
        return jsonVisit((m) -> {
            new StateEngine().deleteTask(id, User.getCurrent().getUserno(),"系统管理员删除任务");
            return "ok";
        });
    }

    @RequestMapping("/close")
    public ModelAndView close(Integer id) {
        return jsonVisit((m) -> {
            new StateEngine().closeTask(id, User.getCurrent().getUserno(),"系统管理员关闭任务");
            return "ok";
        });
    }
    @RequestMapping("/getuser")
    public ModelAndView getuser(String userno) {
        return jsonVisit((m) -> {
            var u = UserApi.getUser(userno);
            if(u!=null){
                return u.getName()+"("+u.getNo()+")";
            }
            return "";
        });
    }


    @RequestMapping("/transfer")
    public ModelAndView transfer(Integer id,String userno) {
        return jsonVisit((m) -> {
            t_task_model task = DbHelper.get((c)->{
                val t=  new t_task_dal().get(c,id);
                return t;
            });
            if(!User.getCurrent().isAdmin()&&!User.getCurrent().getUserno().equals(task.getFlow_approve_node())){
                throw new FlowException("没有权限访问该任务:id"+id);
            }
            new StateEngine().transfer(id, userno,(!task.getFlow_approve_userno().equals(User.getCurrent().getUserno())?"系统":"用户")+"执行转交任务");
            return "ok";
        });
    }

    @RequestMapping("/approve")
    public ModelAndView approve(Integer id,String approveResult,String remark,String variables_json) {
        return jsonVisit((m) -> {
            var variables_json_t = variables_json;
            if(StringUtils.isEmpty(variables_json_t)){
                variables_json_t="{}";
            }
            var variablesMap = JsonUtils.deserialize(variables_json_t, new TypeReference<HashMap<String,String>>() {});
            val variables = new ArrayList<Variable>();
            variablesMap.forEach((k,v)->{
                variables.add(new Variable(k,v,""));
            });
            t_task_model task = DbHelper.get((c)->{
                val t=  new t_task_dal().get(c,id);
                return t;
            });
            if(!User.getCurrent().isAdmin()&&!User.getCurrent().getUserno().equals(task.getFlow_approve_node())){
                throw new FlowException("没有权限访问该任务:id"+id);
            }
            new StateEngine().doTask(id,User.getCurrent().getUserno(),approveResult,remark,variables);
            return "ok";
        });
    }

    @RequestMapping("/detail")
    public ModelAndView detail(Integer id) {
        html.s2("id",id);
        //管理员,任务，发起人 三个角色
        return pageVisit((m)-> {
            if(id==null){
                throw new FlowException("id不能为空");
            }
            Ref<t_task_model> task = new Ref<>(null);
            Ref<t_flow_model> flow = new Ref<>(null);
            Ref<List<t_approve_log_model>> logs = new Ref<>(null);
            Ref<t_model_model> model = new Ref<>(null);
            DbHelper.call((c)->{
                val t=  new t_task_dal().get(c,id);
                val f = new t_flow_dal().get(c,t.flow_id);
                val ls = new t_approve_log_dal().getList(c,t.flow_id);
                val m1 = new t_model_dal().get(c,f.model_id);
                task.setData(t);
                flow.setData(f);
                logs.setData(ls);
                model.setData(m1);
            });
            if(!User.getCurrent().isAdmin()&&!User.getCurrent().getUserno().equals(task.getData().flow_approve_userno)&&!User.getCurrent().getUserno().equals(flow.getData().getApprove_userno())){
                throw new FlowException("没有权限访问该任务:id"+id);
            }
            var variables = JsonUtils.deserialize(flow.getData().flow_variable_json, new TypeReference<List<Variable>>() {});
            var variablesMap = new HashMap<String,Object>();
            variables.forEach(c->{
                variablesMap.put(c.getKey(),c.getValue());
            });
            var xml = XmlUtil.deserialize(model.getData().xml,Xml.class);
            var node = xml.getNodes().stream().filter(n->n.getTitle().equals(task.getData().getFlow_approve_node())).findFirst();
            if(!node.isPresent()){
                throw new FlowException("当前流程无法找到审批节点:"+node.get().getTitle());
            }

            html.s2("variables", variablesMap);
            html.s2("approvelogs",logs.getData());
            html.s2("node", node.get());
            html.s2("approveResults",node.get().getApproveResults());
            html.s2("isapprove",(User.getCurrent().isAdmin()||User.getCurrent().getUserno()==task.getData().flow_approve_userno)&&task.getData().getTask_state()==(byte) TaskStateEnum.waiting.Value);
            var paint = new PaintProvider().paint(xml.getNodes());
            html.s2("parint_nodes",JsonUtils.serialize(paint.getNodes()));
            html.s2("parint_links",JsonUtils.serialize(paint.getLinks()));
            html.s2("task",task.getData());
            html.s2("flow",flow.getData());
        });
    }

    @RequestMapping("/form")
    public ModelAndView form(Integer taskid) {
        //管理员,任务，发起人 三个角色
        return pageVisit((m)-> {
            if(taskid==null){
                throw new FlowException("taskid不能为空");
            }
            Ref<t_task_model> task = new Ref<>(null);
            Ref<t_flow_model> flow = new Ref<>(null);
            Ref<List<t_approve_log_model>> logs = new Ref<>(null);
            Ref<t_model_model> model = new Ref<>(null);
            DbHelper.call((c)->{
                val t=  new t_task_dal().get(c,taskid);
                val f = new t_flow_dal().get(c,t.flow_id);
                val ls = new t_approve_log_dal().getList(c,t.flow_id);
                val m1 = new t_model_dal().get(c,f.model_id);
                task.setData(t);
                flow.setData(f);
                logs.setData(ls);
                model.setData(m1);
            });
            if(!User.getCurrent().isAdmin()&&!User.getCurrent().getUserno().equals(task.getData().flow_approve_userno)&&!User.getCurrent().getUserno().equals(flow.getData().getApprove_userno())){
                throw new FlowException("没有权限访问该任务:taskid"+taskid);
            }
            var xml = XmlUtil.deserialize(model.getData().xml,Xml.class);
            var node = xml.getNodes().stream().filter(n->n.getTitle().equals(task.getData().getFlow_approve_node())).findFirst();
            if(!node.isPresent()){
                throw new FlowException("当前流程无法找到审批节点:"+node.get().getTitle());
            }
            var variables = JsonUtils.deserialize(flow.getData().flow_variable_json, new TypeReference<List<Variable>>() {});
            var variablesMap = new HashMap<String,Object>();
            variables.forEach(c->{
                variablesMap.put(c.getKey(),c.getValue());
            });
            var permission = new FormPermissionProvider().permissionMap(flow.getData().id,xml.getFormPermissions(),variables,User.getCurrent().getUserno(),task.getData().flow_approve_node);

            html.s2("variables", JsonUtils.serialize(variablesMap));
            html.s2("permission", JsonUtils.serialize(permission));
            html.s2("nodeTitle", node.get().getTitle());

            String requestHeader = request.getHeader("user-agent");
            if(CommonUtil.isMobileDevice(requestHeader)){
                html.s2("form_html",model.getData().mobile_form_url);
            }else{
                html.s2("form_html",model.getData().pc_form_url);
            }
            html.s2("task",JsonUtils.serialize(task.getData()));
            flow.getData().setFlow_variable_json("");
            html.s2("flow",JsonUtils.serialize(flow.getData()));
        });
    }

    @RequestMapping("/model")
    public ModelAndView model(Integer id)
    {
        val id2 = (id==null?0:id);
        html.s2("id",id2);
        html.s2("checkuser",false);
        return pageVisit((m)-> {
            var model = DbHelper.get(c -> {
                return new t_model_dal().get(c, id2);
            });
            if (model != null) {
                var xml = new Xml().fromXml(model.getXml());
                html.s2("json",xml.toJson()); ;
            }
            else{
                html.s2("json",null);
            }
        });
    }
}
